package com.ggb.reactive.controller.user

import com.ggb.reactive.domain.entity.Setmeal
import com.ggb.reactive.domain.vo.DishItemVO
import com.ggb.reactive.extension.log
import com.ggb.reactive.model.WebResult
import com.ggb.reactive.repository.SetmealRepository
import com.ggb.reactive.service.SetmeaDishService
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import lombok.RequiredArgsConstructor
import org.springframework.data.redis.core.ReactiveRedisTemplate
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import reactor.core.publisher.Mono
import reactor.core.scheduler.Schedulers
import reactor.kotlin.core.publisher.switchIfEmpty


@RestController("userSetmealController")
@RequestMapping("/user/setmeal")
@RequiredArgsConstructor
@Tag(name = "C端-套餐浏览接口")
class SetmealController(
    private val setmealRepository: SetmealRepository,
    private val setmealDishService: SetmeaDishService,
    private val reactiveRedisTemplate: ReactiveRedisTemplate<String, Any>
) {

    @GetMapping("/list")

    @Operation(summary = "根据分类id查询套餐")
    fun list(categoryId: Long): Mono<WebResult<List<Setmeal>>> {
        val key = "setmealCache_$categoryId"
        return reactiveRedisTemplate.opsForValue().get(key)
            .flatMap { cachedDishes ->
                // 如果从缓存中获取到了数据
                log.info("从缓存中获取套餐列表{}", cachedDishes)
                Mono.just(cachedDishes as List<Setmeal>)
            }
            .switchIfEmpty {
                // 如果缓存中没有数据，则执行默认逻辑
                setmealRepository.findSetmealByCategoryId(categoryId)
                    .collectList()
                    .publishOn(Schedulers.boundedElastic())
                    .doOnNext { setmeals ->

                        val seamealList = setmeals.map {
                            it.updateTime = null
                            it.createTime = null
                            it
                        }
                        reactiveRedisTemplate.opsForValue().set(key, seamealList)
                            .subscribe()
                    }
            }
            .map { WebResult.success(it) }
            .switchIfEmpty(Mono.just(WebResult.success(emptyList())))

    }


    @GetMapping("dish/{id}")
    @Operation(summary = "根据套餐id查询包含的菜品列表")
    fun detail(@PathVariable id: Long): Mono<WebResult<List<DishItemVO>>> {
        return setmealDishService.getDishItemBySetmealId(id)
            .collectList()
            .map { WebResult.success(it) }
            .switchIfEmpty(Mono.just(WebResult.error("未查询到套餐")))
    }
}

